package com.ezops.poc.validations.validators.converter;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Utility class for checking type validation of Alphanumeric field.
 * Alphanumeric is nothing but string but we have to make sure it adhere to the
 * given format.
 * <p>
 * Since the value itself is string , so its is by default in the required type
 * but there are some known format , the data should be in that format. The
 * known formats as of now are
 * <p>
 * (x-y char), (<x char), (>x char),(x char)
 * 
 * TODO - Split this class into two parts, AlphaConverter and
 * AlphaNumericConverter.
 * 
 * @author vgaurav
 * 
 */

public class EzopsAlpahnumericConverter implements ITypeConverter {

	private static Pattern rangePattern = Pattern
			.compile("^([0-9]{1,2})-([0-9]{1,2}).*?");
	private static Pattern lessThanRangePattern = Pattern
			.compile("^<([0-9]{1,2}).*?");
	private static Pattern greaterThanRangePattern = Pattern
			.compile("^>([0-9]{1,2}).*?");
	private static Pattern fixedSizePattern = Pattern
			.compile("^([0-9]{1,2}).*?");

	private String rangeCheckPatternFormat = "^[a-zA-Z0-9_\\s\\.',]{%d,%d}$";
	private String lessThanCheckPatternFormat = "^[a-zA-Z0-9_\\s\\.',]{1,%d}$";
	private String greaterThanCheckPatternFormat = "^[a-zA-Z0-9_\\s\\.',]{%d,}$";

	@Override
	public void tryConvert(String value, String format)
			throws ConversionException, UnknownFormatException {

		if (format == null || format.equals("")) {
			return;
		}
		//Not a mandatory chk, if present then only do validation
		if (value == null || value.equals("")) {
			return;
		}
		
		// No need to check the type, just check the format.
		Matcher rangerMatcher = rangePattern.matcher(format);
		Matcher lessThanMatcher = lessThanRangePattern.matcher(format);
		Matcher greaterThanMatcher = greaterThanRangePattern.matcher(format);
		Matcher fixedMatcher = fixedSizePattern.matcher(format);
		if (rangerMatcher.find()) {
			int minSize = Integer.parseInt(rangerMatcher
					.group(1));
			int maxSize = Integer.parseInt(rangerMatcher
					.group(2));

			String pattern = String.format(rangeCheckPatternFormat, minSize,
					maxSize);
			if (Pattern.matches(pattern, value) == false) {
				throw new ConversionException("Alphanumeric", value,
						"The value" + value + " is not in range " + minSize
								+ " -" + maxSize);
			}

		} else if (lessThanMatcher.find()) {
			
			int minSize = Integer.parseInt(lessThanMatcher
					.group(1));

			String pattern = String.format(lessThanCheckPatternFormat, minSize);
			if (Pattern.matches(pattern, value) == false) {
				throw new ConversionException("Alphanumeric", value,
						"The value" + value + " is not less size than "
								+ minSize);
			}

		} else if (greaterThanMatcher.find()) {
			int maxSize = Integer.parseInt(greaterThanMatcher.group(1));

			String pattern = String.format(greaterThanCheckPatternFormat,
					maxSize);
			if (Pattern.matches(pattern, value) == false) {
				throw new ConversionException("Alphanumeric", value,
						"The value" + value + " is not greater then size  "
								+ maxSize);
			}
		} else if (fixedMatcher.find()) {
			int size = Integer.parseInt(fixedMatcher.group(
					1));
			if (value.length() != size) {
				throw new ConversionException("Alphanumeric", value,
						"The value" + value + " is not of size " + size);
			}
		} else {
			throw new UnknownFormatException(format, "Not known format");
		}

	}

}
